import SwiftUI
import CoreTelephony
import Combine
import UIKit
import SystemConfiguration.CaptiveNetwork
import CoreLocation

class DeviceInfoViewModel: ObservableObject {
    @Published var deviceName: String = ""
    @Published var deviceModel: String = ""
    @Published var systemVersion: String = ""
    @Published var batteryLevel: String = ""
    @Published var batteryState: String = ""
    @Published var storageCapacity: String = ""
    @Published var freeDiskSpace: String = ""
    @Published var localIPAddress: String = ""
    @Published var systemLanguage: String = ""
    @Published var networkOperator: String = ""

    private var locationManager = CLLocationManager()

    init() {
        self.deviceName = UIDevice.current.name
        self.deviceModel = getDeviceModel()
        self.systemVersion = UIDevice.current.systemVersion
        self.updateBatteryInfo()
        self.getStorageInfo()
        self.getLocalIPAddress()
        self.systemLanguage = Locale.current.languageCode ?? "Unknown"
        self.networkOperator = getNetworkOperator()
        
        // Enable battery monitoring
        UIDevice.current.isBatteryMonitoringEnabled = true
        
        // Register for battery state and level change notifications
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(batteryDidChange),
            name: UIDevice.batteryStateDidChangeNotification,
            object: nil
        )
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(batteryLevelDidChange),
            name: UIDevice.batteryLevelDidChangeNotification,
            object: nil
        )
    }
    
    private func getDeviceModel() -> String {
        var systemInfo = utsname()
        uname(&systemInfo)
        let model = withUnsafePointer(to: &systemInfo.machine) {
            $0.withMemoryRebound(to: CChar.self, capacity: Int(MemoryLayout<utsname>.size)) {
                String(cString: $0)
            }
        }
        return mapToDeviceName(model)
    }
    
    private func mapToDeviceName(_ model: String) -> String {
        let deviceModels = [
            "iPhone1,1": "iPhone",
            "iPhone1,2": "iPhone 3G",
            "iPhone2,1": "iPhone 3GS",
            "iPhone3,1": "iPhone 4",
            "iPhone3,2": "iPhone 4",
            "iPhone3,3": "iPhone 4",
            "iPhone4,1": "iPhone 4S",
            "iPhone5,1": "iPhone 5",
            "iPhone5,2": "iPhone 5",
            "iPhone5,3": "iPhone 5c",
            "iPhone5,4": "iPhone 5c",
            "iPhone6,1": "iPhone 5s",
            "iPhone6,2": "iPhone 5s",
            "iPhone7,1": "iPhone 6 Plus",
            "iPhone7,2": "iPhone 6",
            "iPhone8,1": "iPhone 6s",
            "iPhone8,2": "iPhone 6s Plus",
            "iPhone8,4": "iPhone SE",
            "iPhone9,1": "iPhone 7",
            "iPhone9,2": "iPhone 7 Plus",
            "iPhone9,3": "iPhone 7",
            "iPhone9,4": "iPhone 7 Plus",
            "iPhone10,1": "iPhone 8",
            "iPhone10,2": "iPhone 8 Plus",
            "iPhone10,3": "iPhone X",
            "iPhone10,4": "iPhone 8",
            "iPhone10,5": "iPhone 8 Plus",
            "iPhone10,6": "iPhone X",
            "iPhone11,2": "iPhone XS",
            "iPhone11,4": "iPhone XS Max",
            "iPhone11,6": "iPhone XS Max",
            "iPhone11,8": "iPhone XR",
            "iPhone12,1": "iPhone 11",
            "iPhone12,3": "iPhone 11 Pro",
            "iPhone12,5": "iPhone 11 Pro Max",
            "iPhone13,1": "iPhone 12 Mini",
            "iPhone13,2": "iPhone 12",
            "iPhone13,3": "iPhone 12 Pro",
            "iPhone13,4": "iPhone 12 Pro Max",
            "iPhone14,4": "iPhone 13 Mini",
            "iPhone14,5": "iPhone 13",
            "iPhone14,2": "iPhone 13 Pro",
            "iPhone14,3": "iPhone 13 Pro Max",
            "iPhone15,2": "iPhone 14 Pro",
            "iPhone15,3": "iPhone 14 Pro Max",
            "iPhone14,7": "iPhone 14",
            "iPhone14,8": "iPhone 14 Plus",
            "iPad1,1": "iPad",
            "iPad2,1": "iPad 2",
            "iPad2,2": "iPad 2",
            "iPad2,3": "iPad 2",
            "iPad2,4": "iPad 2",
            "iPad3,1": "iPad 3rd Gen",
            "iPad3,2": "iPad 3rd Gen",
            "iPad3,3": "iPad 3rd Gen",
            "iPad3,4": "iPad 4th Gen",
            "iPad3,5": "iPad 4th Gen",
            "iPad3,6": "iPad 4th Gen",
            "iPad4,1": "iPad Air",
            "iPad4,2": "iPad Air",
            "iPad4,3": "iPad Air",
            "iPad5,3": "iPad Air 2",
            "iPad5,4": "iPad Air 2",
            "iPad6,11": "iPad 5th Gen",
            "iPad6,12": "iPad 5th Gen",
            "iPad7,5": "iPad 6th Gen",
            "iPad7,6": "iPad 6th Gen",
            "iPad8,1": "iPad Pro 11-inch (1st Gen)",
            "iPad8,2": "iPad Pro 11-inch (1st Gen)",
            "iPad8,3": "iPad Pro 11-inch (1st Gen)",
            "iPad8,4": "iPad Pro 11-inch (1st Gen)",
            "iPad8,5": "iPad Pro 12.9-inch (3rd Gen)",
            "iPad8,6": "iPad Pro 12.9-inch (3rd Gen)",
            "iPad8,7": "iPad Pro 12.9-inch (3rd Gen)",
            "iPad8,8": "iPad Pro 12.9-inch (3rd Gen)",
            // Add other device models here
        ]
        
        return deviceModels[model] ?? "Unknown"
    }
    
    private func updateBatteryInfo() {
        let batteryLevel = UIDevice.current.batteryLevel
        self.batteryLevel = batteryLevel == -1 ? "未知" : "\(Int(batteryLevel * 100))%"
        
        switch UIDevice.current.batteryState {
        case .unknown:
            self.batteryState = "未知"
        case .unplugged:
            self.batteryState = "未连接"
        case .charging:
            self.batteryState = "充电中"
        case .full:
            self.batteryState = "已充满"
        @unknown default:
            self.batteryState = "未知"
        }
    }
    
    private func getStorageInfo() {
           let fileURL = URL(fileURLWithPath: NSHomeDirectory() as String)
           if let attributes = try? FileManager.default.attributesOfFileSystem(forPath: fileURL.path),
              let systemSize = attributes[.systemSize] as? NSNumber,
              let freeSize = attributes[.systemFreeSize] as? NSNumber {
               self.storageCapacity = String(format: "%.2f GB", systemSize.doubleValue / (1024 * 1024 * 1024))
               self.freeDiskSpace = String(format: "%.2f GB", freeSize.doubleValue / (1024 * 1024 * 1024))
           }
       }
    
    private func getLocalIPAddress() {
        var address: String?
        var ifaddr: UnsafeMutablePointer<ifaddrs>?
        if getifaddrs(&ifaddr) == 0 {
            var ptr = ifaddr
            while ptr != nil {
                defer { ptr = ptr?.pointee.ifa_next }
                let interface = ptr!.pointee
                let name = String(cString: interface.ifa_name)
                if name == "en0" {
                    let addr = withUnsafePointer(to: &interface.ifa_addr.pointee) {
                        $0.withMemoryRebound(to: sockaddr_in.self, capacity: 1) {
                            $0.pointee
                        }
                    }
                    address = String(cString: inet_ntoa(addr.sin_addr))
                }
            }
            freeifaddrs(ifaddr)
        }
        self.localIPAddress = address ?? "Unknown"
    }
    
    private func getNetworkOperator() -> String {
        let networkInfo = CTTelephonyNetworkInfo()
        if let carrier = networkInfo.serviceSubscriberCellularProviders?.first?.value {
            return carrier.carrierName ?? "Unknown"
        }
        return "Unknown"
    }
    
    @objc private func batteryDidChange(notification: Notification) {
        self.updateBatteryInfo()
    }
    
    @objc private func batteryLevelDidChange(notification: Notification) {
        self.updateBatteryInfo()
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
}
